/*
* (C) Copyright 2013 Philip Kirchhoff 
* 
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
*-------------------------------------------------------------------------------
* This file is part of the DataLogger library by Philip Kirchhoff
* https://code.google.com/p/pk-data-logger/
* SVN: http://pk-data-logger.googlecode.com/svn/trunk
*-------------------------------------------------------------------------------
* Module    : DlTimestamp.cpp   
* Author    : Kirchhoff, Philip
* Date      : 01.04.2013
*-------------------------------------------------------------------------------
* Function definitions for class DlTimestamp
*   
*-------------------------------------------------------------------------------
* Change History:
* 01.04.2013  Kirchhoff 	Created
--------------------------------------------------------------------------------
*/

#include <iostream>
#include <sstream>
#include <iomanip>

#include "DlTimestamp.h"

using namespace std;

/**************************************************************************//**
* @brief Creates an unatilialised timestamp object
******************************************************************************/
DlTimestamp::DlTimestamp()
	: mUSecond(0)
{
	time_t rawtime;
	time ( &rawtime );
    timeStruct = *(localtime(&rawtime));
	// Set dylight saving time flag
	timeStruct.tm_isdst = 1;
}

/**************************************************************************//**
* @brief Creates timestamp object from another one
******************************************************************************/
DlTimestamp::DlTimestamp(const DlTimestamp& other)
: timeStruct(other.timeStruct),
	mUSecond(other.mUSecond)
{
}

/**************************************************************************//**
* @brief Converts the timestamp to a DataLogger .cfg-file string
* @return String represantation of the timestamp
******************************************************************************/
std::string DlTimestamp::toDlString()
{
	double dSec = (double)timeStruct.tm_sec;
	dSec += (double)mUSecond/1.0e+6;

	stringstream sStr;
	sStr << timeStruct.tm_mday << "/";
	sStr << timeStruct.tm_mon+1 << "/";
	sStr << timeStruct.tm_year+1900 << ",";
	if(timeStruct.tm_hour < 10)
		sStr << "0";
	sStr << timeStruct.tm_hour << ":";
	if(timeStruct.tm_min < 10)
		sStr << "0";
	sStr << timeStruct.tm_min << ":";
	if(dSec < 10.0)
		sStr << "0";
	sStr << fixed << setprecision(6) << dSec;
	return sStr.str();
}

/**************************************************************************//**
* @brief Creates a new timestamp that differs a specified number of 
*			microseconds
* @param microSeconds Time difference in microseconds
*\details The time differnce can be either positive or negative
******************************************************************************/
DlTimestamp DlTimestamp::diffUs(long long microSeconds)
{
	// Add own microseconds to differnce
    long long uSecs = this->mUSecond + microSeconds;
	// Calculate seconds from microseconds
    long long seconds = uSecs/1000000;
	// Calculate residual microseconds
    long long uSecsRes = uSecs%1000000;

	// Correction for negative values
	if(uSecsRes < 0)
	{
		seconds -= 1;
		uSecsRes += 1000000;
	}

	// Convert to time_t
	time_t thisTime = mktime(&(this->timeStruct));
	// Calculate new time_t from diff seconds 
	time_t newTime = thisTime + seconds;
	// Generate new timetamp
	DlTimestamp tsNew;
    tsNew.timeStruct = *(localtime(&newTime));
	// Add residual microseconds
	tsNew.mUSecond = (int)uSecsRes;

	return tsNew;
}
